package cn.com.java.filter;

import cn.com.java.core.RedisKey;
import cn.com.java.core.ResponseEntity;
import cn.com.java.model.Claims;
import cn.com.java.utils.JWTUtils;
import cn.com.java.utils.RedisUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import io.micrometer.common.util.StringUtils;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

/**
 * @author liushuntao
 * @date 2024/1/25
 */
//@Component
@Slf4j
@RequiredArgsConstructor
public class JWTAuthenticationFilter extends OncePerRequestFilter {

    private final RedisUtils redisUtils;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //获取当前请求的uri
        String uri = request.getRequestURI();
        logger.info("请求路径:" + uri);
        //判断是否是认证请求路径
        //是：直接放行
        if (uri.endsWith("/SysUser/login") || uri.endsWith("/SysUser/logout") || uri.startsWith("/swagger-ui")
                || uri.endsWith("doc.html") || uri.startsWith("/webjars/css") || uri.startsWith("/webjars/js")
                || uri.startsWith("/v3/api-docs") || uri.startsWith("/favicon.ico")
                || uri.startsWith("**/*.html") || uri.endsWith("/webjars/springfox-swagger-ui")
                || uri.startsWith("/swagger-resources")|| uri.startsWith("/images")) {
            filterChain.doFilter(request, response);
            return;
        }

        //否：获取请求头中携带的token
        String authorization = request.getHeader("Authorization");
        logger.info("携带authorization:" + authorization);

        //判断是否携带token
        //否：抛出异常
        if (StringUtils.isBlank(authorization)) {
            logger.info("未查询到token");
            return;
        }

        String realToken = authorization.replace("Bearer ", "");
        if (redisUtils.hHasKey(RedisKey.TOKEN_USER, realToken)) {
            filterChain.doFilter(request, response);
        } else {
            //是：校验jwt有效性
            ResponseEntity responseE = JWTUtils.verifyToken(realToken);
            Claims data = (Claims) responseE.getData();
            log.info("data ={}", data);

            if (ObjectUtils.isEmpty(data)) {
                logger.info("token失效");
                return;
            }

            // 验证token对象是否存在及验证token是否过期
            if (ObjectUtils.isEmpty(data)) {
                logger.info("token无效或者已经失效");
                return;
            }
            if (responseE.getCode() != 200) {
                logger.info("token无效");
                return;
            }

            filterChain.doFilter(request, response);
        }

    }

}
